﻿namespace FileSecurityManager.BizLogic
{
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;

    public class SecureFileLogic
    {
        /// <summary>
        /// Encrypts the specified target file.
        /// </summary>
        /// <param name="targetFile">The target file.</param>
        /// <param name="password">The password.</param>
        public static void Encrypt(string sInputFilename,
            string sOutputFilename,
            string sKey)
        {
            FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);

            FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);
            
            ////
            UTF8Encoding utf8 = new UTF8Encoding();
            MD5CryptoServiceProvider hashProvider = new MD5CryptoServiceProvider();
            byte[] tdesKey = hashProvider.ComputeHash(utf8.GetBytes(sKey));
            TripleDESCryptoServiceProvider tdesAlgorithm = new TripleDESCryptoServiceProvider
            {
                Key = tdesKey,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };
            ICryptoTransform encryptor = tdesAlgorithm.CreateEncryptor();
            CryptoStream cryptostream = new CryptoStream(fsEncrypted, encryptor, CryptoStreamMode.Write);
            byte[] bytearrayinput = new byte[fsInput.Length];
            fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
            cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
            cryptostream.Close();
            fsInput.Close();
            fsEncrypted.Close();

            FileInfo fi = new FileInfo(sInputFilename);
            FileInfo fo = new FileInfo(sOutputFilename);
            Directory.SetCurrentDirectory(fi.DirectoryName);
            File.Replace(fo.Name, fi.Name, "fo.bak");
            File.Delete("fo.bak");

            File.SetAttributes(fi.FullName, File.GetAttributes(fi.FullName) | FileAttributes.Temporary);
            ////

            //DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
            //DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            //DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            //ICryptoTransform desencrypt = DES.CreateEncryptor();

            //CryptoStream cryptostream = new CryptoStream(fsEncrypted,
            //   desencrypt,
            //   CryptoStreamMode.Write);

            //byte[] bytearrayinput = new byte[fsInput.Length];
            //fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
            //cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
            //cryptostream.Close();
            //fsInput.Close();
            //fsEncrypted.Close();

            //FileInfo fi = new FileInfo(sInputFilename);
            //FileInfo fo = new FileInfo(sOutputFilename);
            //Directory.SetCurrentDirectory(fi.DirectoryName);
            //File.Replace(fo.Name, fi.Name, "fo.bak");
            //File.Delete("fo.bak");

            //File.SetAttributes(fi.FullName, File.GetAttributes(fi.FullName) | FileAttributes.Temporary);
        }

        /// <summary>
        /// Decrypts the specified source file.
        /// </summary>
        /// <param name="sourceFile">The source file.</param>
        /// <param name="password">The password.</param>
        public static void Decrypt(string sInputFilename,
         string sOutputFilename,
         string sKey)
        {
            FileInfo fi = new FileInfo(sInputFilename);
            File.SetAttributes(fi.FullName, File.GetAttributes(fi.FullName) & ~FileAttributes.Temporary);
            /////
            UTF8Encoding utf8 = new UTF8Encoding();
            MD5CryptoServiceProvider hashProvider = new MD5CryptoServiceProvider();
            byte[] tdesKey = hashProvider.ComputeHash(utf8.GetBytes(sKey));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            // Step 3. Setup the decoder
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider
            {
                Key = tdesKey,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };
            
            //Create a file stream to read the encrypted file back.
            FileStream fsread = new FileStream(sInputFilename,
               FileMode.Open,
               FileAccess.Read);

            ICryptoTransform decryptor = TDESAlgorithm.CreateDecryptor();
            CryptoStream cryptostreamDecr = new CryptoStream(fsread, decryptor, CryptoStreamMode.Read);
            //Print the contents of the decrypted file.
            StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
            fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
            fsDecrypted.Flush();
            fsDecrypted.Close();
            cryptostreamDecr.Close();

            FileInfo fo = new FileInfo(sOutputFilename);
            Directory.SetCurrentDirectory(fi.DirectoryName);
            File.Replace(fo.Name, fi.Name, "fo.bak");
            File.Delete("fo.bak");
        }
    }
}
